#ifdef DEBUG
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG(...)
#endif

#define LISTENING_PORT 55555
#define LISTENING_ADDR INADDR_ANY

typedef struct _auth {
    char user[32];
    char passwd[32];
} auth_t;

#define DATA_OFFSET (80 * sizeof(char) + 3 * sizeof(int))
typedef struct _file {
    char file[80]; // only this field is valid for request
    int  size;     // size of 0 implies file not found
    int  chunk_size;
    int  offset;
    char data[1024];
} file_t;

typedef enum _cmds_e {
    INVALID_CMD = 0,
    AUTH_REQ    = 1,
    AUTH_RESP   = 2,
    FILE_REQ    = 3,
    FILE_RESP   = 4
} COMMANDS_E;

// This is the message that is exchanged between the server and the client.
// It is a union for the sake of simplicity. It is an overhead for the messages
// that the client initiates (ex: authentication, where only username/password
// is needed but being a union means the data portion of 1024 extra bytes also
// get transmitted. This can be optimized by using separate structures for each
// type of message.
typedef struct _msg {
    COMMANDS_E cmd;
    union {
        auth_t a;
        file_t f;
    } u;
} msg_t;

// Get username and password from the user. The password is not echoed on the
// screen and has been tested on linux/macOS X. May not work on Windows and
// might need changes to get the program to compile
#include <termios.h>
int getPass(char *u, char *p)
{
    struct termios old, new;

    printf("Username: ");
    scanf("%s", u);
    printf("Password: ");
    /* Turn echoing off and fail if we can't. */
    if (tcgetattr (fileno (stdin), &old) != 0) {
        perror("tcgetattr");
        return -1;
    }
    new = old;
    new.c_lflag &= ~ECHO;
    if (tcsetattr (fileno (stdin), TCSAFLUSH, &new) != 0) {
        perror("tcsetattr");
        return -1;
    }

    /* Read the password. */
    scanf("%s", p);

    /* Restore terminal. */
    (void) tcsetattr (fileno (stdin), TCSAFLUSH, &old);

    return 0;
}
